/*
 * @Description: 图片压缩
 * @Author: HuiSir<https://gitee.com/huisir001>
 * @Date: 2025-09-15 10:45:12
 * @LastEditTime: 2025-09-16 09:29:46
 */

/**
 * 图片压缩配置参数
 */
export interface CompressConfig {
  maxWidth?: number; // 最大宽度（可选）
  maxHeight?: number; // 最大高度（可选）
  quality?: number; // 压缩质量 (0-1, 默认0.8)
  outputType?: "blob" | "dataURL"; // 输出格式 (默认'blob')
}

/**
 * 图片压缩核心函数
 * @param config 压缩配置对象
 * @returns Promise<CompressResult> 压缩结果
 */
export default async function compressImage(
  file: string | File | Blob,
  config: CompressConfig = {}
): Promise<Blob | string> {
  // 参数校验
  if (
    typeof file !== "string" &&
    !(file instanceof File) &&
    !(file instanceof Blob)
  ) {
    throw new Error("Invalid file type. Must be string(URL), File, or Blob.");
  }

  // 参数默认值处理
  const {
    maxWidth = Infinity,
    maxHeight = Infinity,
    quality = 0.8,
    outputType = "blob",
  } = config;

  try {
    // 1. 加载图片
    const img = await createImage(file);

    // 2. 计算缩放尺寸（保持宽高比）
    let { naturalWidth: width, naturalHeight: height } = img;
    if (width > maxWidth || height > maxHeight) {
      const ratio = Math.min(maxWidth / width, maxHeight / height);
      width = Math.floor(width * ratio);
      height = Math.floor(height * ratio);
    }

    // 3. 创建Canvas并绘制
    const canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext("2d")!;
    ctx.drawImage(img, 0, 0, width, height);

    // 4. 根据配置输出结果
    try {
      if (outputType === "blob") {
        const blob = await new Promise<Blob>((resolve) => {
          canvas.toBlob((blob) => resolve(blob!), "image/jpeg", quality);
        });
        return blob;
      } else {
        const dataURL = canvas.toDataURL("image/jpeg", quality);
        return dataURL;
      }
    } catch (error) {
      console.error("Image compression failed:", error);
      throw error;
    } finally {
      // 5. 内存清理（关键步骤）
      canvas.remove(); // 释放Canvas内存
      URL.revokeObjectURL(img.src); // 释放图片对象内存
    }
  } catch (error) {
    console.error("Image compression failed:", error);
    throw error;
  }
}

/**
 * 创建图片对象
 */
function createImage(file: string | File | Blob): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = typeof file === "string" ? file : URL.createObjectURL(file);

    img.crossOrigin = "Anonymous";

    img.onload = () => {
      URL.revokeObjectURL(url);
      resolve(img);
    };

    img.onerror = () => {
      URL.revokeObjectURL(url);
      reject(new Error("Image load failed"));
    };

    img.src = url;
  });
}

// 使用示例
// compressImage("https://example.com/large-image.jpg", {
//   maxWidth: 800,
//   maxHeight: 600,
//   quality: 0.7, // 可选
//   outputType: "blob", // 可选 'dataURL'
// })
//   .then((result) => {
//     if (result.type === "blob") {
//       // 处理Blob结果
//       const formData = new FormData();
//       formData.append("image", result.data, "compressed.jpg");
//       console.log("压缩后Blob大小:", result.data.size + " bytes");
//     } else {
//       // 处理Base64结果
//       console.log("Base64数据长度:", result.data.length);
//     }
//   })
//   .catch((error) => console.error("压缩失败:", error));
